package com.blockmeta.bbs.baselibrary.runtime

import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.liveData
import com.blockmeta.bbs.baselibrary.base.app.BaseApp
import kotlinx.coroutines.Dispatchers

/**
 * @CreateDate:   2020-07-28 14:17
 * @Author:       Lewis Weng
 * @Description:  MVVM基础架构接口
 */
interface IArchView<VM : IArchVM> {
    fun initViewModel(): VM?
}

open class IArchVM : ViewModel() {
    fun getApp() = BaseApp.getApp()
}

//model，混淆keep IModel的所有实现类
interface IModel {}

//VM层的Data 通过订阅Repo层的Data（异步） 来通知View层
inline fun <reified T> MediatorLiveData<T>.observerSource(source: LiveData<T>) {
    addSource(source) {
        value = it
    }
}

//协程异步请求
fun <T> asyncLiveData(ioFunc: (suspend (T) -> Unit)? = null): LiveData<T> = liveData(Dispatchers.IO) {

}

data class LiveDataSource<T>(var status: SourceStatus, var code: Int? = 0, var data: T? = null, var msg: String? = null, var err: Throwable? = null) {
    var progress: Int = 0
    //额外需要透传的参数
    var extraMap: HashMap<String, Any>? = null

    enum class SourceStatus {
        SUCCESS, ERROR, LOADING, PROGRESS
    }

    fun isSuccess(): Boolean {
        return status == SourceStatus.SUCCESS && data != null
    }

    fun isLoading(): Boolean {
        return status == SourceStatus.LOADING
    }

    fun isError(): Boolean {
        return status == SourceStatus.ERROR
    }

    fun extra(key: String, value: Any): LiveDataSource<T> {
        if (extraMap == null) {
            extraMap = hashMapOf()
        }
        extraMap?.put(key, value)
        return this
    }

    companion object {
        fun <T> loading(): LiveDataSource<T> {
            return LiveDataSource(SourceStatus.LOADING)
        }

        fun <T> success(code: Int?, data: T, msg: String?): LiveDataSource<T> {
            return LiveDataSource(SourceStatus.SUCCESS, code, data, msg, null)
        }

        fun <T> error(code: Int?, msg: String?, err: Throwable?): LiveDataSource<T> {
            return LiveDataSource(SourceStatus.ERROR, code, null, msg, err)
        }
    }

}
